package com.quickly.develop.common.commonExport;

import java.lang.reflect.Field;

/**
 * 复制对象数据
 * 
 * @author lifz
 */
public class BeanUtil {

	/**
	 * 根据名称取得属性
	 * 
	 * @param fieldName 名称
	 * @param T 数据类型
	 * @return 属性
	 */
	public static Field getFieldByName(String fieldName, Class<?> T) {
		
		Field field = null;
		Class<?> clazz = T;

		for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
			try {
				field = T.getDeclaredField(fieldName);
				break;
			} catch (NoSuchFieldException e) {
			} catch (SecurityException e) {
			}
		}
		return field;
	}

	/**
	 * 取得属性值
	 * 
	 * @param field 属性
	 * @param obj 目标数据
	 * @return 设置值
	 */
	public static Object getFieldValue(Field field, Object obj) {
		
		Object value = null;
		try {
			field.setAccessible(true);
			value = field.get(obj);
		} catch (IllegalArgumentException e) {
		} catch (IllegalAccessException e) {
		}
		return value;
	}

	/**
	 * 设置属性值
	 * 
	 * @param field 属性
	 * @param obj 对象
	 * @param value 设置内容
	 */
	public static void setFieldValue(Field field, Object obj, Object value) {
		try {
			field.setAccessible(true);
			field.set(obj, value);
		} catch (IllegalArgumentException e) {
		} catch (IllegalAccessException e) {
		}
	}

	/**
	 * 根据类型创建对象
	 * 
	 * @param T
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T newInstance(Class<?> T) {
		T obj = null;
		try {
			obj = (T) T.newInstance();
		} catch (InstantiationException e) {
		} catch (IllegalAccessException e) {
		}
		return obj;
	}

	/**
	 * 拷贝数据
	 * 
	 * @param bean 源数据
	 * @param T 复制对象类型
	 * @return 复制对象
	 */
	public static <T> T copyBean(Object src, Class<?> T) {
		
		Object idObj = null;
		
		T obj = newInstance(T);

		Field idFld = getFieldByName("id", T);
		if (null != idFld) {
			idObj = newInstance(idFld.getType());
			setFieldValue(idFld, obj, idObj);
		}

		Field[] beanfields = src.getClass().getDeclaredFields();
		for (Field f : beanfields) {
			Object value = getFieldValue(f, src);
			if (null == value) {
				continue;
			}
			Field toField = getFieldByName(f.getName(), T);
			if (null == toField) {
				if (null != idFld) {
					toField = getFieldByName(f.getName(), idFld.getType());
					if (null == toField) {
						continue;
					} else {
						setFieldValue(toField, idObj, value);
					}
				}
			} else {
				setFieldValue(toField, obj, value);
			}
		}
		return obj;
	}
}
